로딩 중이에요... 🐣
4. 배포하기 | ✅ 저자: 이유정(박사)
엔트포인트의 위치
버킷이름:
보안그룹
보안그룹ID
VPC ID
서브넷ID
복사했을때는 공백 들어간 부분을 삭제해야 합니다.
README에 자신이 프로젝트를 제작하며 작업했던 내용을 꼼꼼히 기록하여 협업시 문제가 없도록 작성합니다.
# Introduction
Django + MySQL 기반 맛집 추천 웹 애플리케이션입니다.
Elastic Beanstalk을 이용해 AWS에 배포합니다.
## 프로젝트 구조
AIRestaurant/
├── proj/ # Django 설정 모듈
├── restaurant/ # 앱
├── templates/ # 템플릿 HTML
├── .env # 환경변수 파일 (Git에 업로드 금지)
├── requirements.txt # 설치 패키지 목록
└── manage.py
## Preparation
가상 환경 설정 (WSL/macOS 공통)
``bash
cd AIRestaurant
python3 -m venv venv
source venv/bin/activate
패키지 설치
``bash
pip install -r requirements.txt
환경 변수 설정(.env)
``bash
PRODUCTION=1
DB_NAME=product_db
DB_USER=db_user
DB_PASSWORD=your_password
DB_HOST=your-db.xxxxx.rds.amazonaws.com
S3_BUCKET=your-s3-bucket-name
AWS CLI 설치
https://aws.amazon.com/ko/cli/
EB CLI 설치 (WSL)
WSL (Ubuntu 환경):
``bash
pip install --upgrade pip
pip install awsebcli --upgrade --user
EB CLI 설치 (macOS)
macOS (Homebrew 사용):
``bash
brew install awsebcli
## AWS 준비
- EC2 가 사용할 보안그룹을 하나 준비하고 해당 보안그룹아이디를 이용하여 EB 환경을 생성해야 합니다.
- RDS 인스턴스를 하나 생성하고 외부 접속을 허용한 다음 EC2가 사용할 보안그룹에도 MySQL 접속을 허용해줍니다.
- IAM에서 `aws-elasticbeanstalk-ec2-role` 에 S3 Full Access 등 해당 버킷의 쓰기 권한을 얼여줘야 합니다.
## Git
Git 설치
https://git-scm.com/book/ko/v2/시작하기-Git-설치
설치 후에
``bash
git init
git add .
it commit -m "Initial Commit"
## Deployment
``bash
eb init
eb create \
--vpc.id VPCID \
--vpc.securitygroups 시큐리티그룹ID \
--vpc.ec2subnets 서브넷ID,서브넷ID... \
--envvars PRODUCTION=1,DB_NAME=product_db,DB_USER=db_user,DB_PASSWORD=비밀번호,DB_HOST=DB엔드포인트,S3_BUCKET=버킷이름 \
--vpc.elbpublic \
--vpc.publicip
수정한 내용을 깃허브에 반영합니다.
git add .
git commit -m "Modify settings.py to use environment variables"
eb create \
--vpc.id VPCID \
# VPC ID (네트워크 경계)
--vpc.securitygroups 보안그룹ID \
# EC2 인스턴스에 부여할 보안 그룹 ID
--vpc.ec2subnets 서브넷ID1,서브넷ID2 \
# EC2가 배치될 퍼블릭 서브넷들
--envvars DB_NAME=...,DB_USER=...,... \
# 환경변수 (RDS, S3, SECRET_KEY 등 전달)
--vpc.elbpublic \ # Load Balancer도 퍼블릭 서브넷 사용
--vpc.publicip # EC2에 퍼블릭 IP 부여
Elastic Beanstalk CLI (EB CLI) 설치
pip install awsebcli --upgrade --break-system-packages
자격 증명 발급
AWS 콘솔 접속 → https://console.aws.amazon.com/
Access Keys 만들기
Access Key ID
별표로 표시된 비밀 키이며, 반드시
.csv 파일 다운로드
하거나 안전한 곳에 복사해 두어야 합니다.
→ 이 값은 다시 볼 수 없습니다! (잊어버리면 새로 발급해야 함)
수동 배포
gunicorn 설치:
pip install gunicorn
pip install PyMySQL
gunicorn --version
PyMySQL --version
pip freeze > requirements.txt
수동으로 추가하는것을 권장합니다
gunicorn>=23.0
PyMySQL>=1.0.2
Procfile 만들기
echo "web: gunicorn 자신의프로젝트이름.wsgi:application" > Procfile
#예시: 수업중 만든 프로젝트 이름이 proj라면
echo "web: gunicorn proj.wsgi:application" > Procfile
eb init
은 Elastic Beanstalk 배포를 위한 초기 설정을 프로젝트에 연결해주는 명령어
eb init
실행 시 AWS 리전을 선택하는 단계
eb init
당신이 한국(서울)을 기반으로 서비스하거나 테스트하려는 경우에는 다음처럼 입력하세요:
10
10) ap-northeast-2 : Asia Pacific (Seoul)
← 한국 리전입니다
aws-access-id
와 aws-secret-key
를 직접 입력 또는 선택
Enter Application Name
은 Elastic Beanstalk에 배포할 애플리케이션의 이름을 입력하는 단계
AIRestaurant
Elastic Beanstalk이 현재 프로젝트가 Python 기반인지 자동으로 감지한 것이고,
당신이 Python을 사용 중인지 묻는 확인 질문:
Is this correct? (Y/n): Y
Elastic Beanstalk에서 어떤 Python 버전과 OS 조합으로 배포할지 선택하라는 의미
2) Python 3.12 running on 64bit Amazon Linux 2023
(default is 1): 2
AWS CodeCommit(버전 관리용 Git 서비스)을 사용할지 묻는 질문
Do you wish to continue with CodeCommit? (Y/n): n
Elastic Beanstalk이 생성하는 EC2 인스턴스에 SSH 접속을 허용할지 묻는 질문
Do you want to set up SSH for your instances? (Y/n): n
보안/접속이 필요 없는 학습용, 또는 단순 배포 목적이면: n
배포전 테스트해보기
# 자신의 DB와 Password확인하기
echo $DB_USER # → restaurant_user
echo $DB_PASSWORD # → DjangoUserPass!123
# 1) (가상환경이 꺼져 있다면) 가상환경 활성화
source .venv/bin/activate
# 2) 환경 변수 내보내기 (반드시 따옴표로 감싸기)
export DB_NAME='restaurant_db'
export DB_USER='restaurant_user'
export DB_PASSWORD='DjangoUserPass!123'
export DB_HOST='airest-d.cfwgaqsu2fpk.ap-northeast-2.rds.amazonaws.com'
export DB_PORT='3306'
mysql \
-h "$DB_HOST" \
-P "$DB_PORT" \
-u admin \
-p
비밀번호를 물어볼땐 마스터암호를 입력한다.
SHOW DATABASES;
USE restaurant_db;
SHOW TABLES;
SHOW GRANTS FOR 'restaurant_user'@'%';
권한이 없다고 나올땐
-- (1) restaurant_user 계정이 없다면 생성, 비밀번호 재설정도 겸함
CREATE USER IF NOT EXISTS 'restaurant_user'@'%'
IDENTIFIED BY 'DjangoUserPass!123';
-- 이미 존재하면 비밀번호만 변경
ALTER USER 'restaurant_user'@'%'
IDENTIFIED BY 'DjangoUserPass!123';
-- (2) restaurant_db 데이터베이스에 대한 모든 권한 부여
GRANT ALL PRIVILEGES
ON restaurant_db.*
TO 'restaurant_user'@'%';
-- (3) 권한 바로 적용
FLUSH PRIVILEGES;
권한 확인
SHOW GRANTS FOR 'restaurant_user'@'%';
# 3) Django 설정 점검
python manage.py check
# 4) DB 연결·마이그레이션 플랜 확인 (실제 반영은 안 함)
python manage.py migrate --plan
# 5) (원한다면) 실제 마이그레이션 실행
# python manage.py migrate
# 6) 개발 서버 구동하여 웹 페이지 띄우기
python manage.py runserver 0.0.0.0:8000
그다음엔 README 하단에 작성해놓은 내용을 터미널에 복사에서 붙여넣고 실행한다.
(venv) youjung@DESKTOP-PJCRMMU:~/AIRestaurant$ eb create \
.....
.....
....
--vpc.publicip
여기서 입력하는 Environment Name은 Elastic Beanstalk에서 운영될 애플리케이션 환경 이름입니다.
그냥 Enter
치면 기본값: AIRestaurant-dev
DNS CNAME prefix는 Elastic Beanstalk에서 생성되는 URL 주소의 서브도메인입니다.
만약 기본값인 AIRestaurant-dev
를 입력하거나 그냥 Enter
를 누르면:
AIRestaurant-dev.ap-northeast-2.elasticbeanstalk.com
이라는 주소로 프로젝트가 배포됩니다.
- 이 주소는 외부에서 여러분의 Django 서비스에 접근할 수 있는 URL이 됩니다.
Elastic Beanstalk에서 "Load Balancer Type"을 선택하는 이 단계는 트래픽을 처리할 방식을 설정하는 것입니다.
옵션 설명
- Classic Load Balancer (CLB)
- 예전 방식 (Legacy)
- Layer 4 (TCP) & Layer 7 (HTTP/HTTPS) 지원
- 단순한 로드 밸런싱
- 소규모/테스트용으로는 괜찮지만, 요즘은 잘 안 씁니다.
- Application Load Balancer (ALB) ← 기본값
- 최신 방식, 가장 일반적
- Layer 7 기반 (HTTP/HTTPS)
- URL 기반 라우팅, WebSocket 지원
- Django, FastAPI, REST API에 적합
- Network Load Balancer (NLB)
- Layer 4 기반 (초고속 TCP)
- 대규모 실시간 통신에 적합 (예: 게임 서버, IoT 등)
- 웹 서비스에는 과한 기능일 수 있음
2)
Application Load Balancer (ALB) 를 선택하세요.
(Django 프로젝트에서는 ALB가 가장 적합합니다.)
Would you like to enable Spot Fleet requests for this environment?" N
“이 환경에 대해 스팟 플릿 요청(Spot Fleet Requests) 을 활성화하시겠습니까?” 그냥 엔터(기본값 N) 를 눌러주세요.
Spot Fleet이란?
- Spot Instance: AWS EC2의 남는 인스턴스를 저렴한 가격에 임시로 빌릴 수 있는 방식.
- Spot Fleet: 여러 스팟 인스턴스를 묶어 자동으로 배포/관리하는 시스템.
- 장점: 비용 절감 (최대 90%까지 저렴)
- 단점: 언제든지 중단될 수 있음 → 안정성이 낮음 우리는 Django 웹 서비스를 배포 중이고, 개발/테스트 단계 또는 지속 서비스를 원할 가능성이 높습니다. 따라서:
❌ 안정성이 중요하므로 "Spot Fleet"은 사용하지 않는 것이 좋습니다.
- Elastic Beanstalk 2.0 이상의 플랫폼(Python 3.13 포함)에서는,
- 서비스 역할(service role)이 필수입니다.
- AWS가 자동으로 역할을 생성해줄 것이고,
- 원한다면 직접 만든 역할을 --service-role 옵션으로 지정할 수도 있습니다.
- "view"라고 입력하면, 생성할 정책 내용을 확인할 수 있습니다.
그냥 ENTER 누르면 자동 생성됩니다.
배포가 시작되며 환경에 따라 5~10분정도 소요될수 있습니다.
Elastic Beanstalk 환경은 만들어졌지만, 애플리케이션 배포에 실패했다는 의미
ERROR: ServiceError - Create environment operation is complete, but with errors. For more information, see troubleshooting documentation.
원인을 찾아보기 위해
eb ssh
이 메시지는 현재 SSH 접속이 설정되지 않은 상태라는 뜻입니다
ERROR: This environment is not set up for SSH. Use "eb ssh --setup" to set up SSH for the environment.
SSH 설정
eb ssh --setup
다음처럼 환경 이름인 AIRestaurant-dev
를 정확히 입력하고 엔터:
To confirm, type the environment name: AIRestaurant-dev
Type a keypair name"은 Elastic Beanstalk 인스턴스(EC2)에 접속하기 위해 사용할 SSH 키 페어 이름입니다.
Type a keypair name.
(Default is aws-eb): airestaurant-key
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
그냥 Enter 두 번 입력 (암호 없이) 진행하세요.
Elastic Beanstalk으로 배포했기 때문에, 배포된 서버 안에서 다음 명령어로 관리자 계정을 새로 생성해야 합니다.
eb ssh
처음으로 해당 EC2 인스턴스에 SSH로 접속할 때 나타나는 정상적인 보안 확인 절차
INFO: Running ssh -i /home/youjung/.ssh/airestaurant-key -o IdentitiesOnly yes ec2-user@3.35.231.39
The authenticity of host '3.35.231.39 (3.35.231.39)' can't be established.
ED25519 key fingerprint is SHA256:DJek3aV/nOjlB5NbntZ+qP3eRmPEx0Hul8BLDw0Z230.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
yes를 입력하세요.
환경변수 세팅
eb setenv \
AWS_ACCESS_KEY_ID=AKIA... \
AWS_SECRET_ACCESS_KEY=... \
AWS_STORAGE_BUCKET_NAME=your-bucket-name \
ALLOWED_HOSTS=restaurant-dev.elasticbeanstalk.com \
SECRET_KEY='django-insecure-...' \
DEBUG=False \
DB_NAME=restaurant_db \
DB_USER=restaurant_user \
DB_PASSWORD='DjangoUserPass!123' \
DB_HOST=127.0.0.1 \
DB_PORT=3306
EB 환경 생성
eb create my-env
my-env
대신 식별하기 쉬운 환경 이름(예: airrest-prod
등)을 입력하세요.
환경생성이 끝나면:
eb deploy
배포가 완료되면 다음 중 하나로 접속할 수 있습니다:
eb open
초기 설정 (migrate & superuser 생성)
eb ssh
cd /var/app/current
source /var/app/venv/*/bin/activate
python manage.py migrate
python manage.py createsuperuser